package com.learn;

import com.learn.model.BlogDomain;
import com.learn.model.CategoryDomain;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class BlogListService {
    /**
     * 存放每个分类下的博客列表
     * 单线程运行，不考虑并发
     */
    private LinkedHashMap<CategoryDomain,List<BlogDomain>> map = new LinkedHashMap<>();

    public void generateBlogListOfAllCategory(List<CategoryDomain> categoryDomains) {
        for (CategoryDomain categoryDomain : categoryDomains) {
            List<BlogDomain> list = MappedFileUtil.readFromCachedFile(BlogDomain.class, categoryDomain.getCategoryChineseName());
            if (CollectionUtils.isEmpty(list)) {
                list = getBlogsOfSpecifiedCategory(categoryDomain);
                MappedFileUtil.write2file(list,categoryDomain.getCategoryChineseName());
            }

            map.put(categoryDomain,list);
        }
    }

    public void generateMarkdownFormat() {

        LinkedHashMap<CategoryDomain, List<BlogDomain>> finalMap = new LinkedHashMap<>();
        {
            /**
             * 对map进行转换
             * 存储
             * key：类别名称
             * value：类别的对象
             */
            LinkedHashMap<String, CategoryDomain> categoryMap = new LinkedHashMap<>();
            for (Map.Entry<CategoryDomain, List<BlogDomain>> entry : this.map.entrySet()) {
                String categoryChineseName = entry.getKey().getCategoryChineseName();
                if (categoryChineseName == null) {
                    throw new RuntimeException();
                }
                categoryMap.put(categoryChineseName, entry.getKey());
            }

            /**
             * 基于下面的优先放前面的类别，来组装最终的map
             */
            ArrayList<String> priorityCategoryList = new ArrayList<>();
            priorityCategoryList.add("spring boot源码解析");
            priorityCategoryList.add("redis源码解析");
            priorityCategoryList.add("JDK源码解析");
            priorityCategoryList.add("mini-dubbo");
            priorityCategoryList.add("Netty重器");
            priorityCategoryList.add("Spring全家桶");
            priorityCategoryList.add("Tomcat Servlet");
            priorityCategoryList.add("Java基础");

            for (String categoryName : priorityCategoryList) {
                CategoryDomain categoryDomain = categoryMap.get(categoryName);

                List<BlogDomain> blogDomains = map.get(categoryDomain);
                finalMap.put(categoryDomain, blogDomains);

                map.remove(categoryDomain);
            }

            /**
             * 把map中剩下的，放到最终的map中
             */
            for (Map.Entry<CategoryDomain, List<BlogDomain>> entry : map.entrySet()) {
                finalMap.put(entry.getKey(), entry.getValue());
            }
        }

        /**
         * 生成markdown格式
         */
        StringBuilder builder = new StringBuilder();
        for (Map.Entry<CategoryDomain, List<BlogDomain>> entry : finalMap.entrySet()) {
            CategoryDomain categoryDomain = entry.getKey();
            /**
             * 一级大标题
             */
            builder.append("#")
                    .append(categoryDomain.getCategoryChineseName())
                    .append("\n");

            builder.append("[总览](")
                    .append(categoryDomain.getHref())
                    .append(")\n");
            List<BlogDomain> list = entry.getValue();
            for (BlogDomain blogDomain : list) {
                builder.append("[")
                        .append(blogDomain.getBlogTitle())
                        .append("]")
                        .append("(")
                        .append(blogDomain.getHref())
                        .append(")\n");
            }
            builder.append("\n\n\n\n");
        }

        log.info("result:{}",builder.toString());
    }

    public List<BlogDomain> getBlogsOfSpecifiedCategory(CategoryDomain categoryDomain) {
        List<BlogDomain> blogs = new ArrayList<>();

        /**
         * 如果本地文件没有读到，则去网络请求，并写入本地文件
         */
        Document doc = null;
        try {
            doc = Jsoup.connect(categoryDomain.getHref()).get();
        } catch (IOException e) {
            log.error("e:{}", e);
            return null;
        }

        Elements elements = doc.select(".entrylistItemTitle");
        if (CollectionUtils.isEmpty(elements)) {
            return new ArrayList<>();
        }

        List<BlogDomain> blogDomains = convert2CategoryDomains(elements, categoryDomain.getCategoryChineseName());
        return blogDomains;
    }


    private List<BlogDomain> convert2CategoryDomains(Elements elements, String categoryChineseName) {
        List<BlogDomain> result = new ArrayList<>();
        for (Element element : elements) {
            BlogDomain blogDomain = new BlogDomain();
            /**
             * 获取链接
             */
            String href = element.attr("href");
            blogDomain.setHref(href);

            /**
             * 获取名称
             */
            TextNode node = (TextNode) element.childNode(0);
            String title = node.toString().trim();
            title = element.getElementsByTag("span").get(0).text();
//            title = element.getAllElements().get(1).getAllElements().get(0)
//                    .toString().replace("<span>","").replace("</span>","");
            blogDomain.setBlogTitle(title);

            /**
             * 设置类别名称
             */
            blogDomain.setCategoryName(categoryChineseName);

            result.add(blogDomain);
        }


        return result;
    }
}
